home *** CD-ROM | disk | FTP | other *** search
/ CyberMycha 2005 May / CyberMycha 05-2005 (Poland).bin / Immortal / cotndemo.exe / AdobeInstall.exe / Reader / JavaScripts / Annots.js < prev   
Encoding:
Text File  |  2002-03-18  |  23.0 KB  |  874 lines

  1. var plugins = app.plugIns;
  2. var nPlugins = plugins.length;
  3. var annotsPresent = false;
  4.  
  5. for (var i = 0; i < nPlugins; i++)
  6.     if (plugins[i].name.toLowerCase() == "annots")
  7.         annotsPresent = true;
  8.  
  9. if (annotsPresent)
  10. {
  11.     var strsToExport =[
  12.         "IDS_SUM_TITLE1",
  13.         "IDS_SUM_TITLE2",
  14.         "IDS_UNNAMED",
  15.         "IDS_SUM_DATE1",
  16.         "IDS_SUM_DATE2",
  17.         "IDS_SUM_AUTHOR1",
  18.         "IDS_SUM_AUTHOR2",
  19.         "IDS_SUM_SUBJ1",
  20.         "IDS_SUM_SUBJ2",
  21.         "IDS_SUM_LABEL1",
  22.         "IDS_SUM_LABEL2",
  23.         "IDS_SUM_PAGE1",
  24.         "IDS_SUM_PAGE2",
  25.         "IDS_SUM_TYPE1",
  26.         "IDS_SUM_TYPE2",
  27.         "IDS_SUM_SEQ1",
  28.         "IDS_SUM_SEQ2",
  29.         "IDS_SUM_NO_ANNOTS1",
  30.         "IDS_SUM_NO_ANNOTS2",
  31.         "IDS_STORE_WEB_DISCUSSIONS",
  32.         "IDS_STORE_DAVFDF",
  33.         "IDS_STORE_FSFDF",
  34.         "IDS_STORE_DATABASE",
  35.         "IDS_STORE_NONE",
  36.         "IDS_PROGRESS_SUMMARIZE",
  37.         "IDS_PROGRESS_SORTING",
  38.         "IDS_PROGRESS_FETCHING",
  39.         "IDS_PROGRESS_FETCHING_BIG",
  40.         "IDS_PROGRESS_ADDING",
  41.         "IDS_PROGRESS_DELETING",
  42.         "IDS_PROGRESS_CHANGING",
  43.         "IDS_ANNOTS_JS_BUILTIN",
  44.         "IDS_DATE_INDETERMINATE"
  45.     ];
  46.  
  47.     for(var n = 0; n < strsToExport.length; n++)
  48.     {
  49.         var strID = strsToExport[n];
  50.  
  51.         eval(strID + " = " + app.getString("Annots", strID).toSource());
  52.     }
  53.  
  54.     console.println(IDS_ANNOTS_JS_BUILTIN);
  55.  
  56.     /* for debugging */
  57.     function debugExcept(e)
  58.     {
  59.         if((typeof app._DEBUG != "undefined") && app._DEBUG)
  60.           console.println(e)
  61.     }
  62.  
  63.     /* Sort methods */
  64.     ANSB_None = 0;
  65.     ANSB_Page = 1;
  66.     ANSB_Seq = 2;
  67.     ANSB_Author = 3;
  68.     ANSB_ModDate = 4;
  69.     ANSB_Type = 5;
  70.  
  71.     ANFB_ShouldPrint = 0;
  72.     ANFB_ShouldView = 1;
  73.     ANFB_ShouldEdit = 2;
  74.     ANFB_ShouldAppearInPanel = 3;
  75.     ANFB_ShouldSummarize = 4;
  76.     ANFB_ShouldExport = 5;
  77.     ANFB_ShouldNone = 6;
  78.  
  79.     /* Field to summary functions by property name */
  80.     ANsums =
  81.     [
  82.     /* None */        function(a){return "*None*";},
  83.     /* Page */        function(a){return IDS_SUM_PAGE1+a.doc.getPageLabel(a.page)+IDS_SUM_PAGE2;},
  84.     /* Sequence */    function(a){return IDS_SUM_SEQ1+a.seqNum+IDS_SUM_SEQ2;},
  85.     /* Author */    function(a){return IDS_SUM_AUTHOR1+a.author+IDS_SUM_AUTHOR2;},
  86.     /* ModDate */    function(a){
  87.         var d = a.modDate; 
  88.         return IDS_SUM_DATE1+ (d ? util.printd(2, a.modDate) : IDS_DATE_INDETERMINATE )+IDS_SUM_DATE2;
  89.         },
  90.     /* Type */        function(a){return IDS_SUM_TYPE1+a.uiType+IDS_SUM_TYPE2;},
  91.     ];
  92.  
  93.     /* Order of summary fields */
  94.     ANsumorder = [ ANSB_Page, ANSB_Seq, ANSB_Author, ANSB_ModDate, ANSB_Type ];
  95.  
  96.     /* binary insertion into sorted list */
  97.     function binsert(a, m)
  98.     {
  99.         var nStart = 0, nEnd = a.length - 1;
  100.  
  101.         while(nStart < nEnd)
  102.         {
  103.             var nMid = Math.floor((nStart + nEnd) / 2);
  104.  
  105.             if(m.toString() < a[nMid].toString())
  106.                 nEnd = nMid - 1;
  107.             else
  108.                 nStart = nMid + 1;
  109.         }
  110.         if((nStart < a.length) && (m.toString() >= a[nStart].toString()))
  111.             a.splice(nStart + 1, 0, m);
  112.         else
  113.             a.splice(nStart, 0, m);
  114.     }
  115.  
  116.     /* perform a worst case n log ( n ) sort with status */
  117.     function isort(a, status)
  118.     {
  119.         var i;
  120.         var aNew = new Array();
  121.  
  122.         if(status)
  123.         {
  124.             app.thermometer.begin();
  125.             app.thermometer.duration = a.length;
  126.             app.thermometer.text = status;
  127.         }
  128.         for(i = 0; i < a.length; i++)
  129.         {
  130.             if(status)
  131.                 app.thermometer.value = i;
  132.             binsert(aNew, a[i]);
  133.         }
  134.         if(status)
  135.             app.thermometer.end();
  136.         return aNew;
  137.     }
  138.  
  139.     function ANsummarize(doc, title, p, r, dest, fs)
  140.     {    /* Summarize annotations sorted primarily by property p */
  141.         app.thermometer.begin();
  142.         app.thermometer.text = IDS_PROGRESS_SUMMARIZE;
  143.  
  144.         if(!ANsums[p])
  145.             p = ANSB_Page;
  146.         if(!title)
  147.             title = IDS_UNNAMED;
  148.  
  149.         /* make sure we have all annots */
  150.         this.syncAnnotScan();
  151.  
  152.         /* Get all summarizable annots on all pages sorted in the given manner */
  153.         var a = doc.getAnnots(-1, p, r, ANFB_ShouldSummarize);
  154.         var t, s;
  155.         var r = new Report();
  156.  
  157.         r.style = "NoteTitle";
  158.         r.size = 3;
  159.         t = IDS_SUM_TITLE1 + title + IDS_SUM_TITLE2;
  160.         r.writeText(t);
  161.         r.divide(3.5);
  162.  
  163.         var i, j, contents;
  164.         var oldHeading;
  165.  
  166.         if(a && a.length > 0)
  167.         {
  168.           app.thermometer.duration = a.length;
  169.           for(i = 0; i < a.length; i++)
  170.           {
  171.             app.thermometer.value = i;
  172.             // maybe do the heading
  173.               r.style = "NoteTitle";
  174.               r.size = 2;
  175.               var heading = (ANsums[p])(a[i]);
  176.               if(heading != oldHeading)
  177.               {
  178.                 if(typeof oldHeading != "undefined")
  179.                   r.writeText(" ");
  180.                 r.writeText(heading);
  181.                 oldHeading = heading;
  182.                 r.divide();
  183.               }
  184.  
  185.               for(j = 0; j < ANsumorder.length; j++)
  186.                   if(ANsumorder[j] != p)
  187.                   {
  188.                       r.size = 1;
  189.                       r.writeText((ANsums[ANsumorder[j]])(a[i]));
  190.                   }
  191.               var contents = a[i].contents;
  192.               if(contents)
  193.               {
  194.                   r.style = "DefaultNoteText";
  195.                   r.size = 1;
  196.                   r.indent();
  197.                   r.writeText(contents);
  198.                   r.writeText(" ");
  199.                   r.outdent();
  200.               }
  201.               else
  202.                   r.writeText(" ");
  203.           }
  204.         }
  205.         else
  206.           r.writeText(IDS_SUM_NO_ANNOTS1 + title + IDS_SUM_NO_ANNOTS2);
  207.         if (typeof dest != "undefined")
  208.             r.save(dest, fs);
  209.         else
  210.             r.open(t);
  211.         app.thermometer.end();
  212.  
  213.         return a ? a.length : 0;
  214.     }
  215. }
  216.  
  217. if(typeof Collab != "undefined")
  218. {
  219.     /* flags used by collaboration
  220.     */
  221.     CBFNiceTableName = 1;
  222.     CBFNiceDBName = 2;
  223.     CBFDBPerDoc = 4;
  224.  
  225.     function CBgetTableDesc(doc, author)
  226.     {
  227.       var frag = Collab.URL2PathFragment(doc.URL);
  228.       var DBName;
  229.       var tableName;
  230.  
  231.       if(doc.collabDBFlags & CBFDBPerDoc)
  232.       {
  233.         DBName = frag;
  234.         tableName = author;
  235.       }
  236.       else
  237.       {
  238.         DBName = "";
  239.         tableName = frag;
  240.       }
  241.  
  242.       if(doc.collabDBFlags & CBFNiceTableName)
  243.         tableName = Collab.hashString(tableName);
  244.       if(doc.collabDBFlags & CBFNiceDBName)
  245.         DBName = Collab.hashString(DBName);
  246.       return {DBName: doc.collabDBRoot + DBName,
  247.         tableName: tableName,
  248.         URL: doc.URL,
  249.         user: author,
  250.         flags: doc.collabDBFlags};
  251.     }
  252.  
  253.     function CBgetTableConnect(desc)
  254.     {
  255.       var e;
  256.  
  257.       try
  258.       {
  259.         var conn = ADBC.newConnection(desc.DBName);
  260.         var stmt = conn.newStatement();
  261.  
  262.         return {conn: conn,
  263.           stmt: stmt,
  264.           tableName: desc.tableName,
  265.           user: desc.user,
  266.           flags: desc.flags};
  267.       }
  268.       catch(e) { debugExcept(e); return false; }
  269.     }
  270.  
  271.     function CBgetInfo(conn, name)
  272.     {
  273.       var e;
  274.  
  275.       try
  276.       {
  277.         conn.stmt.execute("select CONTENTS from \"" + conn.tableName + "\" where AUTHOR like ?;",
  278.           "~" + name + "~");
  279.         conn.stmt.nextRow();
  280.         return conn.stmt.getColumn("CONTENTS").value;
  281.       }
  282.       catch(e) { debugExcept(e); return false; }
  283.     }
  284.  
  285.     function CBsetInfo(conn, name, value)
  286.     {
  287.       var e;
  288.  
  289.       /* add the field */
  290.       try { return conn.stmt.execute("insert into \"" + conn.tableName + "\" (AUTHOR, CONTENTS) values (?, ?);",
  291.           "~" + name + "~",
  292.           value); }
  293.       catch(e) { debugExcept(e); return false; }
  294.     }
  295.  
  296.     function CBcreateTable(desc)
  297.     {
  298.       var e;
  299.  
  300.       try
  301.       {
  302.         var conn = ADBC.newConnection(desc.DBName);
  303.         var stmt = conn ? conn.newStatement() : null;
  304.  
  305.         /* come up with the SQL query to do it */
  306.         var sql1 = "create table \"" + desc.tableName + "\" (AUTHOR varchar(64), PAGE integer, NAME varchar(64), CONTENTS text, DATA image);";
  307.         var sql2 = "create table \"" + desc.tableName + "\" (AUTHOR varchar(64), PAGE integer, NAME varchar(64), CONTENTS clob, DATA blob);";
  308.  
  309.         var conn = {conn: conn,
  310.           stmt: stmt,
  311.           tableName: desc.tableName,
  312.           user: desc.user,
  313.           flags: desc.flags};
  314.  
  315.         // first try...
  316.         try
  317.         {
  318.           stmt.execute(sql1);
  319.         } catch(e) { debugExcept(e); }
  320.         // second try...
  321.         try
  322.         {
  323.           stmt.execute(sql2);
  324.         } catch(e) { debugExcept(e); }
  325.         // these will throw if the table wasn't created
  326.         CBsetInfo(conn, "URL", desc.URL);
  327.         CBsetInfo(conn, "creator", desc.user);
  328.         return conn;
  329.       }
  330.       /* we failed... */
  331.       catch(e) { debugExcept(e); return false; }
  332.     }
  333.  
  334.     function CBconnect(desc, bDoNotCreate)
  335.     {
  336.       var conn = CBgetTableConnect(desc);
  337.       var e;
  338.  
  339.       /* if we can't get the URL from it, it doesn't exist */
  340.       if(!CBgetInfo(conn, "URL"))
  341.       {
  342.         if (!bDoNotCreate)
  343.           conn = CBcreateTable(desc);
  344.         else
  345.           return false;
  346.       }
  347.  
  348.       /* here it is! */
  349.       return conn;
  350.     }
  351.  
  352.     /* mapping of annot types to data properties */
  353.     CBannotdata =
  354.     {
  355.         FileAttachment:    "FSCosObj",
  356.         Sound:            "SCosObj"
  357.     };
  358.  
  359.     /* returns the data fork for an annot */
  360.     function CBannotData(annot)
  361.     {
  362.       var prop = CBannotdata[annot.type];
  363.       var stm = prop ? Collab.cosObj2Stream(annot[prop]) : null;
  364.  
  365.       if(stm)
  366.         stm.type = ADBC.SQLT_LONGVARBINARY;
  367.       return stm;
  368.     }
  369.  
  370.     /* sets the data fork of an annot */
  371.     function CBannotSetData(annot, data)
  372.     {
  373.       var prop = CBannotdata[annot.type];
  374.  
  375.       if(prop)
  376.         annot[prop] = data;
  377.     }
  378.  
  379.  
  380.     /* recursive function that deletes a reply chain */
  381.     function CBDeleteReplyChain(disc)
  382.     {
  383.         var replies = Discussions.getDiscussions(disc);
  384.  
  385.         if (replies && (replies.length == 1))
  386.         {
  387.             var currentReply = replies[0];
  388.             var looper = 1;
  389.             while (looper)
  390.             {
  391.                 /*
  392.                 ** There better only be one reply 
  393.                 */
  394.                 var saveChild = Discussions.getDiscussions(currentReply);
  395.  
  396.     //            console.println("Delete reply");
  397.                 currentReply.Delete();
  398.  
  399.                 if (saveChild && (saveChild.length == 1))
  400.                     currentReply = saveChild[0];
  401.                 else
  402.                     looper = 0;
  403.             }
  404.         }
  405.  
  406.     }
  407.  
  408.     /* gets the reply chain, stuffs it in a stream */
  409.     /* and then puts it in the annot */
  410.     function CBGetReplyChain(dstAnnot, discussion)
  411.     {
  412.         var discList = Discussions.getDiscussions(discussion);
  413.  
  414.         var cos = Collab.newWrStreamToCosObj();
  415.  
  416.         var data = 0;
  417.         while (discList && (discList.length > 0))
  418.         {
  419.             data = 1;
  420.             cos.write(discList[0].Text);
  421.     //        console.println("Write to cos stream " + discList[0].Text.length + " characters");
  422.  
  423.             discList = Discussions.getDiscussions(discList[0]);
  424.         }
  425.  
  426.         if (data == 1)
  427.             CBannotSetData(dstAnnot, cos.getCosObj());
  428.     }
  429.  
  430.     /* get the stream and puts the data as replies */
  431.     function CBPutReplyChain(discussion, bookmark, srcAnnot)
  432.     {
  433.         var cosStream = CBannotData(srcAnnot);
  434.  
  435.         if(cosStream)
  436.         {
  437.             var s = cosStream.read(Collab.wdBlockSize);
  438.  
  439.             while (discussion && (s.length > 0))
  440.             {
  441.                 discussion = Discussions.addDiscussion(discussion, "Data", s, bookmark);
  442.  
  443.                 s = null;
  444.             
  445.                 s = cosStream.read(Collab.wdBlockSize);
  446.             }
  447.         }
  448.     }
  449.  
  450.     /* ADBC based annot enumerator constructor
  451.     */
  452.     function ADBCAnnotEnumerator(parent, sorted)
  453.     {
  454.       /* store away parameters */
  455.       this.parent = parent;
  456.       this.sorted = sorted;
  457.       /* add enumeration method */
  458.       this.next = function()
  459.       {
  460.         var e;
  461.  
  462.         try
  463.         {
  464.           if(!this.conn)
  465.           {
  466.             this.conn = CBconnect(this.parent.desc, true);
  467.             this.conn.stmt.execute("select CONTENTS from \"" + this.parent.desc.tableName + "\" where AUTHOR not like '~%~'" +
  468.               (this.sorted ? " order by PAGE, NAME;" : ";"));
  469.           }
  470.           this.conn.stmt.nextRow();
  471.           return eval(this.conn.stmt.getColumn("CONTENTS").value);
  472.         }
  473.         catch(e) { debugExcept(e); return false; }
  474.       }
  475.     }
  476.  
  477.     /* ADBC based annot store constructor
  478.     */
  479.     function ADBCAnnotStore(doc, user)
  480.     {
  481.       this.desc = CBgetTableDesc(doc, user);
  482.       this.enumerate = function(sorted)
  483.       {
  484.         return new ADBCAnnotEnumerator(this, sorted);
  485.       }
  486.       this.complete = function(toComplete)
  487.       {
  488.         var i;
  489.         var conn = CBconnect(this.desc,true);
  490.  
  491.         if (conn) 
  492.             {
  493.           for(i = 0; toComplete && i < toComplete.length; i++)
  494.           {
  495.             if(CBannotdata[toComplete[i].type])
  496.             {
  497.               var e;
  498.   
  499.               try
  500.               {
  501.                 conn.stmt.execute("select DATA from \"" + this.desc.tableName + "\" where PAGE = ? and NAME like ?;",
  502.                   toComplete[i].page, toComplete[i].name);
  503.                 conn.stmt.nextRow();
  504.                 var cos = Collab.newWrStreamToCosObj();
  505.  
  506.                 conn.stmt.getColumn("DATA", ADBC.Binary | ADBC.Stream, cos);
  507.                 CBannotSetData(toComplete[i], cos.getCosObj());
  508.               }
  509.               catch(e) { debugExcept(e);}
  510.             }
  511.               }
  512.         }
  513.         return true;
  514.       }
  515.       this.update = function(toDelete, toAdd, toUpdate)
  516.       {
  517.         var i;
  518.         var e;
  519.         var conn = CBconnect(this.desc);
  520.  
  521.         for(i = 0; toDelete && i < toDelete.length; i++)
  522.         {
  523.           try
  524.           {
  525.             conn.stmt.execute("delete from \"" + this.desc.tableName + "\" where PAGE = ? and NAME like ?;",
  526.               toDelete[i].page, toDelete[i].name);
  527.           }
  528.           catch(e) { debugExcept(e);}
  529.         }
  530.         for(i = 0; toAdd && i < toAdd.length; i++)
  531.         {
  532.           try
  533.           {
  534.             conn.stmt.execute("insert into \"" + this.desc.tableName + "\" (AUTHOR, PAGE, NAME, CONTENTS, DATA) values (?, ?, ?, ?, ?);",
  535.               toAdd[i].author, toAdd[i].page, toAdd[i].name, toAdd[i].toSource(), CBannotData(toAdd[i]));
  536.           }
  537.           catch(e) { debugExcept(e);}
  538.         }
  539.         for(i = 0; toUpdate&& i < toUpdate.length; i++)
  540.         {
  541.           try
  542.           {
  543.             conn.stmt.execute("update \"" + this.desc.tableName + "\" set CONTENTS = ?, DATA = ? where PAGE = ? and NAME like ?;",
  544.               toUpdate[i].toSource(), CBannotData(toUpdate[i]), toUpdate[i].page, toUpdate[i].name);
  545.           }
  546.           catch(e) { debugExcept(e);}
  547.         }
  548.         return true;
  549.       }
  550.     }
  551.  
  552.     /* Munge an URL such that Web Discussions won't put our data in the discussions pane
  553.     */
  554.     function WDmungeURL(url)
  555.     {
  556.         return url + "/ACData";
  557.     }
  558.  
  559.     /* Web discussions based annot enumerator constructor
  560.     */
  561.     function WDAnnotEnumerator(parent, sorted)
  562.     {
  563.     //  console.println("WDAnnotEnumerator(): Begin");
  564.  
  565.       this.parent = parent;
  566.       this.sorted = sorted;
  567.       this.next = function()
  568.       {
  569.     //    console.println("WDAnnotEnumerator.next(): Begin");
  570.  
  571.         if(!this.discussions)
  572.         {
  573.     //        console.println("WDAnnotEnumerator.next(): get discussions "+WDmungeURL(this.parent.doc.URL));
  574.  
  575.           this.discussions = Discussions.getDiscussions(WDmungeURL(this.parent.doc.URL));
  576.  
  577.           app.thermometer.begin();
  578.           app.thermometer.text = IDS_PROGRESS_FETCHING;
  579.           if(this.discussions) // always sort as our completion callback relies on a sorted list
  580.           {
  581.             this.discussions = isort(this.discussions, IDS_PROGRESS_SORTING);
  582.             app.thermometer.duration = this.discussions.length;
  583.           }
  584.           this.index = 0;
  585.         }
  586.         /* skip non-Acro discussions */
  587.         while(this.discussions && this.index < this.discussions.length && this.discussions[this.index] == "[Discussion]")
  588.           app.thermometer.value = this.index++;
  589.         if(!this.discussions || this.index >= this.discussions.length)
  590.         {
  591.           app.thermometer.end();
  592.           return false;
  593.         }
  594.         return eval(this.discussions[this.index++].Text);
  595.       }
  596.     }
  597.  
  598.     /* Web discussion based annot store constructor
  599.     */
  600.     function WDAnnotStore(doc, user)
  601.     {
  602.     //  console.println("WDAnnotStore(): Begin");
  603.  
  604.       this.doc = doc;
  605.       this.user = user;
  606.       this.enumerate = function(sorted)
  607.       {
  608.     //    console.println("WDAnnotStore.enumerate(): Begin");
  609.         return new WDAnnotEnumerator(this, sorted);
  610.       }
  611.       this.complete = function(toComplete)
  612.       {
  613.     //    console.show();
  614.     //    console.println("WDAnnotStore.toComplete(): Begin");
  615.  
  616.         var i,j;
  617.     //    console.println("get discussions for "+WDmungeURL(this.doc.URL));
  618.         var discussions = Discussions.getDiscussions(WDmungeURL(this.doc.URL));
  619.  
  620.         if (discussions && discussions.length) 
  621.         {
  622.             // sort them to perform fast searches
  623.             // JS sort is a SLOW qsort... use our worst case N log ( N )
  624.             discussions = isort(discussions, IDS_PROGRESS_SORTING);
  625.  
  626.             app.thermometer.begin();
  627.             app.thermometer.text = IDS_PROGRESS_FETCHING_BIG;
  628.             app.thermometer.duration = toComplete.length;
  629.             for(i = 0, j = 0; discussions && (i < toComplete.length) && (j < discussions.length); app.thermometer.value = ++i)
  630.             {
  631.                 //console.println("disussion " + i);
  632.  
  633.                 // create a string that'll look like the corresponding discussion
  634.                 var discString = Discussions.makeDiscussionString(toComplete[i].page, toComplete[i].name);
  635.                 //console.println("Descriptive string \"" + discString + "\"");
  636.  
  637.                 // keep skipping annots while they are "less" than the current one
  638.                 while(discString > discussions[j])
  639.                     j++;
  640.  
  641.                 // if we found it
  642.                 if(discString == discussions[j])
  643.                 {
  644.                     //console.println("found it - Annot to Complete " + i + " is in discussion slot " + j);
  645.                     //console.println("subject "+discussions[j].Subject);
  646.  
  647.                     /*
  648.                     ** We found the discussion, now gather replys which will
  649.                     ** contain the "data" for the stream
  650.                     */
  651.                     if (CBannotdata[toComplete[i].type])
  652.                         CBGetReplyChain(toComplete[i], discussions[j]);
  653.  
  654.                 }
  655.  
  656.             }
  657.             app.thermometer.end();
  658.         }
  659.         return true;
  660.       }
  661.       this.update = function(toDelete, toAdd, toUpdate)
  662.       {
  663.     //    console.println("WDAnnotStore.update(): Begin");
  664.  
  665.         // get the list of discussions
  666.     //    console.println("WDAnnotStore.update(): get discussions "+WDmungeURL(this.doc.URL();
  667.         var discussions = Discussions.getDiscussions(WDmungeURL(this.doc.URL));
  668.         var i, j;
  669.  
  670.         // if we got any...
  671.         if(discussions && discussions.length)
  672.         {
  673.     //        console.println("WDAnnotStore.update(): got some " + discussions.length);
  674.             // sort them to perform fast searches
  675.             discussions = isort(discussions, IDS_PROGRESS_SORTING);
  676.  
  677.             // if we've got any to update
  678.             if(toUpdate && toUpdate.length)
  679.             {
  680.                 app.thermometer.begin();
  681.                 app.thermometer.text = IDS_PROGRESS_CHANGING;
  682.                 app.thermometer.duration = toUpdate.length;
  683.     //            console.println("WDAnnotStore.update(): updating " + toUpdate.length);
  684.  
  685.                 for(i = 0, j = 0; i < toUpdate.length && j < discussions.length; app.thermometer.value = ++i)
  686.                 {
  687.                   // create a string that'll look like the corresponding discussion
  688.                   var discString = Discussions.makeDiscussionString(toUpdate[i].page, toUpdate[i].name);
  689.  
  690.                   // keep skipping annots while they are "less" than the current one
  691.                   while(discString > discussions[j])
  692.                     j++;
  693.                   // if we found it
  694.                   if(discString == discussions[j])
  695.                   {
  696.                     // then update it!
  697.                     CBDeleteReplyChain(discussions[j]);
  698.                     discussions[j].Delete();
  699.  
  700.                     var bookmark = Discussions.makeBookmark(toUpdate[i].page, toUpdate[i].name);
  701.                     discussions[j] = Discussions.addDiscussion(WDmungeURL(this.doc.URL), "Markup", toUpdate[i].toSource(), bookmark);
  702.                     CBPutReplyChain(discussions[j], bookmark, toUpdate[i]);
  703.                     j++;
  704.                   }
  705.                 }
  706.                 app.thermometer.end();
  707.             }
  708.  
  709.             // delete is just like update
  710.             if(toDelete && toDelete.length) 
  711.             {
  712.                 app.thermometer.begin();
  713.                 app.thermometer.text = IDS_PROGRESS_DELETING;
  714.                 app.thermometer.duration = toDelete.length;
  715.     //            console.println("WDAnnotStore.update(): deleting " + toDelete.length);
  716.                 for(i = 0, j = 0; i < toDelete.length && j < discussions.length; app.thermometer.value = ++i)
  717.                 {
  718.                   var discString = Discussions.makeDiscussionString(toDelete[i].page, toDelete[i].name);
  719.  
  720.                   while(discString > discussions[j])
  721.                     j++;
  722.  
  723.                   if(discString == discussions[j])
  724.                   {
  725.                     CBDeleteReplyChain(discussions[j]);
  726.  
  727.                     discussions[j].Delete();
  728.  
  729.                     j++;
  730.                   }
  731.                 }
  732.                 app.thermometer.end();
  733.             }
  734.         }
  735.         if(toAdd && toAdd.length)
  736.         {
  737.             app.thermometer.begin();
  738.             app.thermometer.text = IDS_PROGRESS_ADDING;
  739.             app.thermometer.duration = toAdd.length;
  740.             for(i = 0; toAdd && i < toAdd.length; app.thermometer.value = ++i)
  741.             {
  742.               var bookmark = Discussions.makeBookmark(toAdd[i].page, toAdd[i].name);
  743.  
  744.         /*
  745.               console.println("WDAnnotStore.update(): adding " + toAdd.length);
  746.               console.println("this.doc.URL \""+ WDmungeURL(this.doc.URL) + "\"");
  747.               console.println("Markup");
  748.               console.println("toAdd[i].toSource() \""+ toAdd[i].toSource() + "\"");
  749.               console.println("bookmark \"" + bookmark + "\"");
  750.         */
  751.  
  752.               var discussion = Discussions.addDiscussion(WDmungeURL(this.doc.URL), "Markup", toAdd[i].toSource(), bookmark);
  753.  
  754.               if (discussion && CBannotdata[toAdd[i].type])
  755.                 CBPutReplyChain(discussion, bookmark, toAdd[i]);
  756.  
  757.             }
  758.             app.thermometer.end();
  759.         }
  760.         return true;
  761.       }
  762.     }
  763.  
  764.     /* Set up default annot stores */
  765.     Collab.addAnnotStore("NONE", IDS_STORE_NONE,
  766.         {create: function(doc, user, settings){ return null; }});
  767.     Collab.setStoreNoSettings("NONE", true);
  768.     if(typeof Discussions != "undefined")
  769.     {
  770.       Collab.addAnnotStore("WD", IDS_STORE_WEB_DISCUSSIONS,
  771.             {create: function(doc, user, settings){ return new WDAnnotStore(doc, user); }});
  772.         Collab.setStoreNoSettings("WD", true);
  773.     }
  774.     if(typeof ADBC != "undefined")
  775.         Collab.addAnnotStore("DB", IDS_STORE_DATABASE,
  776.             {create: function(doc, user, settings){ doc.collabDBRoot = settings; doc.collabDBFlags = CBFNiceTableName; return (settings && settings != "") ? new ADBCAnnotStore(doc, user) : null; }});
  777.     Collab.addAnnotStore("DAVFDF", IDS_STORE_DAVFDF,
  778.         {create: function(doc, user, settings){ return (settings && settings != "") ? new FSAnnotStore(doc, user, settings + doc.Collab.docID + "/", "CHTTP") : null; }});
  779.     Collab.addAnnotStore("FSFDF", IDS_STORE_FSFDF,
  780.         {create: function(doc, user, settings){ return (settings && settings != "") ? new FSAnnotStore(doc, user, settings + doc.Collab.docID + "/") : null; }});
  781.     Collab.setStoreFSBased("FSFDF", true);
  782.  
  783.     // Web Discussion data block size
  784.     Collab.wdBlockSize = 16384;
  785. }
  786.  
  787. function CBdef(a, b)
  788. {
  789.   return typeof a == "undefined" ? b : a;
  790. }
  791.  
  792. function Matrix2D(a, b, c, d, h, v)
  793. {
  794.     this.a = CBdef(a, 1);
  795.     this.b = CBdef(b, 0);
  796.     this.c = CBdef(c, 0);
  797.     this.d = CBdef(d, 1);
  798.     this.h = CBdef(h, 0);
  799.     this.v = CBdef(v, 0);
  800.     this.fromRotated = function(doc, page)
  801.     {
  802.         page = CBdef(page, 0);
  803.  
  804.         var cropBox = doc.getPageBox("Crop", page);
  805.         var mediaBox = doc.getPageBox("Media", page);
  806.         var mbHeight = mediaBox[1] - mediaBox[3];
  807.         var mbWidth = mediaBox[2] - mediaBox[0];
  808.         var rotation = doc.getPageRotation(page);
  809.         var m = new Matrix2D(1, 0, 0, 1, cropBox[0] - mediaBox[0], cropBox[3] - mediaBox[3]);
  810.  
  811.         if(rotation == 90)
  812.             return this.concat(m.rotate(Math.asin(1.0)).translate(mbHeight, 0));
  813.         else if(rotation == 180)
  814.             return this.concat(m.rotate(2.0 * -Math.asin(1.0)).translate(mbWidth, mbHeight));
  815.         else if(rotation == 270)
  816.             return this.concat(m.rotate(-Math.asin(1.0)).translate(0, mbWidth));
  817.         return this.concat(m);
  818.     }
  819.     this.transform = function(pts)
  820.     {
  821.         var result = new Array(pts.length);
  822.  
  823.         if(typeof pts[0] == "object")
  824.             for(var n = 0; n < pts.length; n++)
  825.                 result[n] = this.transform(pts[n]);
  826.         else
  827.             for(var n = 0; n + 1 < pts.length; n += 2)
  828.             {
  829.                 result[n] = this.a * pts[n] + this.c * pts[n + 1] + this.h;
  830.                 result[n + 1] = this.b * pts[n] + this.d * pts[n + 1] + this.v;
  831.             }
  832.         return result;
  833.     }
  834.     this.concat = function(m)
  835.     {
  836.         return new Matrix2D(
  837.             (this.a * m.a) + (this.b * m.c),
  838.             (this.a * m.b) + (this.b * m.d),
  839.             (this.c * m.a) + (this.d * m.c),
  840.             (this.c * m.b) + (this.d * m.d),
  841.             (this.h * m.a) + (this.v * m.c) + m.h,
  842.             (this.h * m.b) + (this.v * m.d) + m.v);
  843.     }
  844.     this.invert = function()
  845.     {
  846.         var result = new Matrix2D;
  847.         var q = this.b * this.c - this.a * this.d;
  848.  
  849.         if (q)
  850.         {
  851.             result.a = - this.d / q;
  852.             result.b = this.b / q;
  853.             result.c = this.c / q;
  854.             result.d = - this.a / q;
  855.             result.h = -(this.h * result.a + this.v * result.c);
  856.             result.v = -(this.h * result.b + this.v * result.d);
  857.         }
  858.         return result;
  859.     }
  860.     this.translate = function(dx, dy)
  861.     {
  862.         return this.concat(new Matrix2D(1, 0, 0, 1, CBdef(dx, 0), CBdef(dy, 0)));
  863.     }
  864.     this.scale = function(sx, sy)
  865.     {
  866.         return this.concat(new Matrix2D(CBdef(sx, 1), 0, 0, CBdef(sy, 1), 0, 0));
  867.     }
  868.     this.rotate = function(t)
  869.     {
  870.         t = CBdef(t, 0);
  871.         return this.concat(new Matrix2D(Math.cos(t), Math.sin(t), -Math.sin(t), Math.cos(t), 0, 0));
  872.     }
  873. }
  874.